        
#ifndef __MUD_MUDPORT_MUDPORT__HEADER_FILE__
#define __MUD_MUDPORT_MUDPORT__HEADER_FILE__

//#include <windows.h>
#include "coid/svc/coidsvc.h"
#include "coid/comm/binstream/netstreamtcp.h"

#include "../mudcore/client/mudcore_client.h"
#include "../Colors.h"

class MudPort
{
    //NET_OPTIONS: acceptor_port 23 nolog_system_calls
    //NET_OPTIONS: nolog

//    friend struct StenchMud;

    uint _core;
    cmd_interface* _cmdin;
    void* _creature;

    dynarray<charstr>   _in_buffer;
    dynarray<charstr>   _out_buffer;
    netstreamtcp _net;

	uint _state;
	MudCore_client _server;
public:

    MudPort()
    {
        _creature = 0;
		_state = 0; // noname
		_net = 0;
    }

    // special functions

    net_fnc_s opcd accept_connect()
    {
		return 0;
    }
	
    net_fnc_s opcd accept_startup_params( cmd_interface& cmd )
    {
        _cmdin = &cmd;
		dynarray<uint> lst;
		_cmdin->find_nodes_of_class( 0, "", "MudCore", MudCore_client::get_version(), lst );
		if( lst.size() == 0 )
			return ersUNAVAILABLE "no MudCore service running";
		
		_core = lst[0];
		opcd e = _server.connect_shared( _core, "localhost:55099" );
		if (e) {
			_out_buffer.push("Failed to attach to mudcore!");
			_state = 99;
			return e;
		}
		_state = 0;
		_server.send_intro_screen(&_out_buffer);
		_out_buffer.push("Enter your name: ");
        return 0;
    }
    
    net_fnc_s opcd accept_connect_shared()
    {
        return 0;
    }

    net_fnc_s opcd accept_destroy()
    {
        _server.unregister_client( _cmdin->get_id() );
        return 0;
    }

    net_fnc_s opcd accept_net_connections( netSocket* socket, uint port )
    {
        _net.assign_socket( *socket );
		
        charstr cmd;
		
		flush();
        for(;;)
        {
			cmd.reset();
            opcd e = _net.read_until( cmd, '\n', 4096);
            if (e)
                return e;
			
			CMDIN_GUARD(_cmdin);
			send(cmd);
        }        
    }

    // client functions

    net_fnc opcd read( net_out dynarray<charstr>& str );
    net_fnc opcd send( net_in const charstr& str );

    // interface functions

    net_fnc_d opcd fetch( net_out dynarray<charstr>& cmds, net_out net_ptr void** creature )
    {
        cmds.takeover( _in_buffer );
        *creature = _creature;
        return 0;
    }
	
    net_fnc_d opcd setinfo( net_ptr void* creature )
    {
        _creature = creature;
        return 0;
    }
	
	opcd flush()
	{
		if( _net.is_open() )
        {
			uint n = _out_buffer.size();
			for (uint i = 0; i < n; ++i)
				_net.xwrite_raw(_out_buffer[i].ptr(), _out_buffer[i].len());
			_out_buffer.reset();
		}
		return 0;
	}

    net_fnc_d opcd flush( net_in const dynarray<charstr>& cmds )
    {
		if( _net.is_open() )
        {
			flush();
            uint n = cmds.size();
            for (uint i = 0; i < n; ++i)
                _net.xwrite_raw( cmds[i].ptr(), cmds[i].len() );
        } else
			_out_buffer.append(cmds);
        return 0;
    }
};

#endif //__MUD_MUDPORT_MUDPORT__HEADER_FILE__